﻿using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEditor;
using Framework;
using System.Reflection;
using Logger = Framework.Logger;

namespace FrameworkEditor
{
    public static class EditorUtils
    {
        public static readonly string assetRootDir = "Assets/" + FrameworkSettings.ResourcesLibName;
        public static readonly string assetRootInBundle = assetRootDir.ToLower();
        public static string GetFileExt(string filePath)
        {
            string extenstion = string.Empty;
            int index = filePath.LastIndexOf(".");
            if (index > -1)
            {
                extenstion = filePath.Substring(index);
            }
            return extenstion;
        }

        /// <summary>
        /// 获取相对于Unity工程Assets目录的路径
        /// </summary>
        /// <param name="filePath"></param>
        /// <returns></returns>
        public static string GetPathRelativeToAssets(string filePath)
        {
            string unityPath = FileHelper.GetUnityPath(filePath);
            int index = unityPath.IndexOf("Assets");
            if (index >= 0)
            {
                return unityPath.Substring(index);
            }
            return unityPath;
        }

        /// <summary>
        /// 获取相对于dirPath目录的文件路径
        /// </summary>
        /// <param name="filePath">文件路径</param>
        /// <param name="dirPath">参考的目录路径</param>
        /// <returns></returns>
        public static string GetRelativePathToDir(string filePath, string dirPath)
        {
            string unityPath = FileHelper.GetUnityPath(filePath);
            if (string.IsNullOrEmpty(dirPath))
            {
                return unityPath;
            }

            dirPath = FileHelper.GetUnityPath(dirPath);
            if (!dirPath.EndsWith("/"))
            {
                dirPath += "/";
            }
            if (unityPath.Contains(dirPath))
            {
                return unityPath.Replace(dirPath, "");
            }
            return unityPath;
        }

        /// <summary>
        /// 获取路径的上层路径
        /// </summary>
        /// <param name="filePath"></param>
        /// <returns></returns>
        public static string GetParentDir(string filePath)
        {
            string unityPath = FileHelper.GetUnityPath(filePath);
            if (string.IsNullOrEmpty(unityPath))
            {
                return unityPath;
            }
            int idx = filePath.LastIndexOf("/");
            return filePath.Substring(0, idx);
        }

        private static Dictionary<int, BuildTarget> PlatformIdBuildTargetTab = new Dictionary<int, BuildTarget>()
        {
            [FrameworkSettings.AndroidPlayer] = BuildTarget.Android,
            [FrameworkSettings.IOSPlayer] = BuildTarget.iOS,
            [FrameworkSettings.WindowsPlayer] = BuildTarget.StandaloneWindows64,
            [FrameworkSettings.OSXPlayer] = BuildTarget.StandaloneOSX,
        };

        /// <summary>
        /// 根据FrameworkSettings中定义的平台数字，获取到对应Unity中的BuildTarget
        /// </summary>
        /// <returns>BuildTarget</returns>
        public static BuildTarget GetBuildTargetFromPlatformId(int platformId)
        {
            if (PlatformIdBuildTargetTab.TryGetValue(platformId, out BuildTarget ret))
            {
                return ret;
            }
            Debug.LogError("EditorUtils.GetBuildTargetFromPlatform, platformId = " + platformId + " is not defined!");
            return BuildTarget.StandaloneWindows64;
        }

        /// <summary>
        /// 根据Unity中的BuildTarget获取到对应FrameworkSettings中定义的平台数字，
        /// </summary>
        /// <returns>platformId</returns>
        public static int GetPlatformIdFromBuildTarget(BuildTarget buildTarget)
        {
            foreach (var kvp in PlatformIdBuildTargetTab)
            {
                Debug.Log("kvp.key = " + kvp.Key + " kvp.value = " + kvp.Value);
                if (kvp.Value == buildTarget)
                {
                    return kvp.Key;
                }
            }
            return FrameworkSettings.AndroidPlayer;
        }

        /// <summary>
        /// 获取当前激活的平台id
        /// </summary>
        /// <returns></returns>
        public static int GetCurPlatformId()
        {
            BuildTarget curTarget = EditorUserBuildSettings.activeBuildTarget;
            return GetPlatformIdFromBuildTarget(curTarget);
        }

        /// <summary>
        /// 切换平台
        /// </summary>
        /// <param name="curTarget"></param>
        public static void SwitchToTarget(BuildTarget curTarget)
        {
            BuildTargetGroup buildTargetGroup = BuildTargetGroup.Android;
            switch (curTarget)
            {
                case BuildTarget.Android:
                    buildTargetGroup = BuildTargetGroup.Android;
                    break;
                case BuildTarget.iOS:
                    buildTargetGroup = BuildTargetGroup.iOS;
                    break;
                case BuildTarget.StandaloneWindows64:
                case BuildTarget.StandaloneOSX:
                    buildTargetGroup = BuildTargetGroup.Standalone;
                    break;
                default:
                    buildTargetGroup = BuildTargetGroup.Android;
                    break;
            }

            if (curTarget != EditorUserBuildSettings.activeBuildTarget)
            {
                EditorUserBuildSettings.SwitchActiveBuildTarget(buildTargetGroup, curTarget);
            }
        }

        /// <summary>
        /// 根据相对于资源库的路径 输出所有语言的资源目录
        /// 传入 effects/material
        /// 输出 Assets/ZResourcesLib/effects/material/
        /// Assets/ZResourcesLib/lang/zh/effects/material/
        /// Assets/ZResourcesLib/lang/en/effects/material/
        /// ...
        /// </summary>
        /// <param name="relativeDir">相对路径</param>
        /// <returns></returns>
        // public static string[] GetLanguageResDir(string relativeDir)
        // {
        //     List<string> ret = new List<string>();
        //     if (relativeDir.EndsWith("/") || relativeDir.StartsWith("/"))
        //     {
        //         Debug.LogError("EditorUtils.GetLanguageResDir relativeDir 的开始和结尾不要有 / 符号！");
        //         return null;
        //     }
        //     ret.Add($"Assets/{FrameworkSettings.ResourcesLibName}/{relativeDir}/");
        //     // Debug.Log(ret[0]);
        //     foreach (var item in LanguageHelper.GetAllLangShortcut())
        //     {
        //         string dir = $"Assets/{FrameworkSettings.ResourcesLibName}/lang/{item}/{relativeDir}/";
        //         // Debug.Log("dir = " + dir);
        //         ret.Add(dir);
        //     }
        //     return ret.ToArray();
        // }

        /// <summary>
        /// Editor下打开目录
        /// </summary>
        /// <param name="dirPath"></param>
        public static void OpenFolder(string dirPath)
        {
#if UNITY_EDITOR
            if (string.IsNullOrEmpty(dirPath)) return;

            dirPath = dirPath.Replace("/", "\\");
            if (!FileHelper.IsDirExists(dirPath))
            {
                Logger.LogWarning("OpenDir fail, no directory!");
                return;
            }
            System.Diagnostics.Process.Start("explorer.exe", dirPath);
#endif
        }

        /// <summary>
        /// 资源加密私钥
        /// </summary>
        private static string defaultPrivateKey = @"<RSAKeyValue><Modulus>kLm/rL5q/8iRO56CeH5jnBzJu7dj9XmcvX8n5Z5w/b5fvA9tOJVfaBKPZW666jvp</Modulus><Exponent>AQAB</Exponent><P>s+/oA+lT9uiaRPnTiz/HjHRtfnSDzNVJ</P><Q>zedivc/ekyqnY0/64hx/u6lIuro2vFGh</Q><DP>P5Lsw60FqIAIOYSXFGTlaR+drAcYph9Z</DP><DQ>PHK5ok/sX/gdvCI23TrQpR9FoswYVaEB</DQ><InverseQ>r15URUZlq9tgUMVMgr6mLwzKjkWtBIDA</InverseQ><D>KHgohw+AMCJPqlI6vaLqC79pEdrIUt48cEQSbHUwL3wMHw9FxiIjAtye1ebXtE4B</D></RSAKeyValue>";

        public static void SetDefaultPrivateKey(string rsaPrivateKey)
        {
            if (string.IsNullOrEmpty(rsaPrivateKey))
            {
                Debug.LogError("EditorUtils.SetDefaultPrivateKey, rsaPrivateKey is null or empty!");
                return;
            }
            byte[] keyData = StringHelper.Base64Str2ByteArray(rsaPrivateKey);
            string rsaKey = StringHelper.ByteArray2Str(keyData);
            //Debug.Log("EditorUtils.SetDefaultPrivateKey, rsaPrivateKey: " + rsaKey);
            defaultPrivateKey = rsaKey;
        }
        /// <summary>
        /// 给数据做aes加密并签名
        /// </summary>
        /// <param name="dataStr">数据</param>
        /// <returns></returns>
        [LuaInterface.NoToLua]
        public static byte[] RsaEncrypt(byte[] srcData)
        {
            if (null == srcData || srcData.Length == 0)
            {
                Logger.LogError("FileHelper.RsaEncrypt, srcData can not be null!");
                return null;
            }
            string dataStr = StringHelper.ByteArray2Str(srcData);
            byte[] encryptData = MD5Util.AESEncrypt(dataStr, GameConfig.AESPassword, GameConfig.AESKeyVector);
            var md5 = MD5Util.ComputeMd5Sign(encryptData);
            string hash = RSAUtil.RSASignData(md5, defaultPrivateKey);
            var hashCode = StringHelper.Base64Str2ByteArray(hash);
            // Debug.LogWarning("hashCode length = " + hashCode.Length);
            int newDataLength = hashCode.Length + encryptData.Length;
            byte[] data = new byte[newDataLength];
            System.Array.Copy(hashCode, data, hashCode.Length);
            System.Array.Copy(encryptData, 0, data, hashCode.Length, encryptData.Length);
            return data;
        }


        /// <summary>
        /// 给数据做签名
        /// </summary>
        /// <param name="dataStr">数据</param>
        /// <returns></returns>
        public static byte[] RsaSign(byte[] srcData)
        {
            if (null == srcData || srcData.Length == 0)
            {
                Logger.LogError("EditorUtils.RsaSign, srcData can not be null!");
                return null;
            }
            var md5 = MD5Util.ComputeMd5Sign(srcData);
            string hash = RSAUtil.RSASignData(md5, defaultPrivateKey);
            var hashCode = StringHelper.Base64Str2ByteArray(hash);
            int newDataLength = hashCode.Length + srcData.Length;
            byte[] data = new byte[newDataLength];
            System.Array.Copy(hashCode, data, hashCode.Length);
            System.Array.Copy(srcData, 0, data, hashCode.Length, srcData.Length);
            return data;
        }

        private static MethodInfo textureSizeMethodInfo;
        public static long GetTextureStorageSize(string texPath)
        {
            if (!FileHelper.IsFileExists(texPath))
            {
                Logger.LogError($"EditorUtils.GetTextureStorageSize, texPath = {texPath} is not exists!");
                return 0;
            }
            Texture tex = AssetDatabase.LoadAssetAtPath<Texture>(texPath);
            return GetTextureStorageSize(tex);
        }

        public static long GetTextureStorageSize(Texture tex)
        {
            if(null == tex)
            {
                Logger.LogError($"EditorUtils.GetTextureStorageSize, tex is null!");
                return 0;
            }
            if (null == textureSizeMethodInfo)
            {
                var assembly = Assembly.GetAssembly(typeof(UnityEditor.Editor));
                var type = assembly.GetType("UnityEditor.TextureUtil");
                textureSizeMethodInfo = type.GetMethod("GetStorageMemorySizeLong");
            }
            return (long)(textureSizeMethodInfo.Invoke(null, new object[] { tex }));
        }
    }
}
